/*********************************************************************
	Rhapsody	: 7.5 
	Login		: kbe
	Component	: DefaultComponent 
	Configuration 	: CodeConfig
	Model Element	: Connector
//!	Generated Date	: Thu, 27, Sep 2012  
	File Path	: DefaultComponent\CodeConfig\Connector.h
*********************************************************************/

#ifndef Connector_H
#define Connector_H

//#[ ignore
#ifdef _MSC_VER
// disable Microsoft compiler warning (debug information truncated)
#pragma warning(disable: 4786)
#endif
//#]

//## auto_generated
#include <oxf\oxf.h>
//## auto_generated
#include <string>
//## auto_generated
#include <algorithm>
//## auto_generated
#include "SOCK_WrapperFacade.h"
//## auto_generated
#include "Default.h"
//## auto_generated
#include <map>
//## auto_generated
#include <iterator>
//## auto_generated
#include <oxf\OMValueCompare.h>
//## class Connector
#include "EventHandler.h"
//## link itsServiceHandler
#include "ServiceHandler.h"
//## auto_generated
#include "Reactor.h"
//## auto_generated
class Reactor;

//## package Default

//## class Connector
template <class SERVICE_HANDLER, class IPC_CONNECTOR> class Connector : public EventHandler {
    ////    Friends    ////
    
    ////    Constructors and destructors    ////
    
public :

    //## operation Connector(Reactor*)
    inline Connector(Reactor* reactor) : itsServiceHandler() {
        //#[ operation Connector(Reactor*)
        itsReactor = reactor;
        
        
        //#]
    }
    
    //## auto_generated
    virtual ~Connector();
    
    ////    Operations    ////
    
    //## operation connect(SERVICE_HANDLER*,INET_Addr*,bool)
    inline void connect(SERVICE_HANDLER* sh, INET_Addr* remote_addr, bool async = false) {
        //#[ operation connect(SERVICE_HANDLER*,INET_Addr*,bool)
        connect_service_handler(sh, remote_addr, async);
        
        //#]
    }
    
    //## operation handleEvent(HANDLE,Event_Type)
    inline virtual int handleEvent(HANDLE h, Event_Type& et) {
        //#[ operation handleEvent(HANDLE,Event_Type)
        complete(h);
        return 0;
        
        //#]
    }

protected :

    //## operation complete(HANDLE)
    inline virtual void complete(const HANDLE& h) {
        //#[ operation complete(HANDLE)
        
        SERVICE_HANDLER *sh = (SERVICE_HANDLER *)getItsServiceHandler(h);
        // activate_service_handler
        if (sh != NULL)
        {
        	SOCK_Stream *stream = new SOCK_Stream();
        	stream->set_handle((SOCKET)h);
        	sh->setPeer_stream_(stream);
        	// Important to save reactor association
        	// It is remove in removeHandler
        	Reactor *saveReactor = itsReactor;
        	itsReactor->removeHandler(h, READ_EVENT); 
        	itsReactor = saveReactor;
        	itsReactor->registerHandler(h, *sh, READ_EVENT);
        }
        //#]
    }
    
    //## operation connect_service_handler(SERVICE_HANDLER*,INET_Addr*,bool)
    inline virtual void connect_service_handler(SERVICE_HANDLER* sh, INET_Addr* remote_addr, bool async) {
        //#[ operation connect_service_handler(SERVICE_HANDLER*,INET_Addr*,bool)
        connector_ = new IPC_CONNECTOR(*remote_addr);
        SOCK_Stream *stream = new SOCK_Stream();
        if (async) {
        	connector_->connecting(*stream, true);
        	handle = (HANDLE)stream->get_handle();
        	itsReactor->registerHandler(handle, *this, READ_EVENT);
        	addItsServiceHandler(handle, sh);
        	//delete stream;
        } else {
        	connector_->connecting(*stream, false);
        	// activate_service_handler
        	sh->setPeer_stream_(stream);
        	itsReactor->registerHandler((HANDLE)stream->get_handle(), *sh, READ_EVENT);
        }
        //#]
    }
    
    ////    Additional operations    ////

public :

    //## auto_generated
    std::map<HANDLE, ServiceHandler*>::const_iterator getItsServiceHandler() const;
    
    //## auto_generated
    std::map<HANDLE, ServiceHandler*>::const_iterator getItsServiceHandlerEnd() const;
    
    //## auto_generated
    void clearItsServiceHandler();
    
    //## auto_generated
    void removeItsServiceHandler(ServiceHandler* p_ServiceHandler);
    
    //## auto_generated
    ServiceHandler* getItsServiceHandler(HANDLE key) const;
    
    //## auto_generated
    void addItsServiceHandler(HANDLE key, ServiceHandler* p_ServiceHandler);
    
    //## auto_generated
    void removeItsServiceHandler(HANDLE key);

protected :

    //## auto_generated
    IPC_CONNECTOR* getConnector_() const;
    
    //## auto_generated
    void setConnector_(IPC_CONNECTOR* p_connector_);
    
    //## auto_generated
    void cleanUpRelations();
    
    ////    Attributes    ////
    
    IPC_CONNECTOR* connector_;		//## attribute connector_
    
    ////    Relations and components    ////
    
    std::map<HANDLE, ServiceHandler*> itsServiceHandler;		//## link itsServiceHandler

public :

    //## operation Connector()
    inline Connector() : itsServiceHandler() {
        //#[ operation Connector()
        //#]
    }
};

//## package Default

//## class Connector
template <class SERVICE_HANDLER, class IPC_CONNECTOR> std::map<HANDLE, ServiceHandler*>::const_iterator Connector<SERVICE_HANDLER, IPC_CONNECTOR>::getItsServiceHandler() const {
    std::map<HANDLE, ServiceHandler*>::const_iterator iter;
    iter = itsServiceHandler.begin();
    return iter;
}

template <class SERVICE_HANDLER, class IPC_CONNECTOR> std::map<HANDLE, ServiceHandler*>::const_iterator Connector<SERVICE_HANDLER, IPC_CONNECTOR>::getItsServiceHandlerEnd() const {
    return itsServiceHandler.end();
}

template <class SERVICE_HANDLER, class IPC_CONNECTOR> void Connector<SERVICE_HANDLER, IPC_CONNECTOR>::clearItsServiceHandler() {
    itsServiceHandler.clear();
}

template <class SERVICE_HANDLER, class IPC_CONNECTOR> void Connector<SERVICE_HANDLER, IPC_CONNECTOR>::removeItsServiceHandler(ServiceHandler* p_ServiceHandler) {
    std::map<HANDLE, ServiceHandler*>::iterator pos = std::find_if(itsServiceHandler.begin(), itsServiceHandler.end(),OMValueCompare<const HANDLE,ServiceHandler*>(p_ServiceHandler));
    if (pos != itsServiceHandler.end()) {
    	itsServiceHandler.erase(pos);
    }
}

template <class SERVICE_HANDLER, class IPC_CONNECTOR> ServiceHandler* Connector<SERVICE_HANDLER, IPC_CONNECTOR>::getItsServiceHandler(HANDLE key) const {
    return (itsServiceHandler.find(key) != itsServiceHandler.end() ? (*itsServiceHandler.find(key)).second : NULL);
}

template <class SERVICE_HANDLER, class IPC_CONNECTOR> void Connector<SERVICE_HANDLER, IPC_CONNECTOR>::addItsServiceHandler(HANDLE key, ServiceHandler* p_ServiceHandler) {
    itsServiceHandler.insert(std::map<HANDLE, ServiceHandler*>::value_type(key, p_ServiceHandler));
}

template <class SERVICE_HANDLER, class IPC_CONNECTOR> void Connector<SERVICE_HANDLER, IPC_CONNECTOR>::removeItsServiceHandler(HANDLE key) {
    itsServiceHandler.erase(key);
}

template <class SERVICE_HANDLER, class IPC_CONNECTOR> IPC_CONNECTOR* Connector<SERVICE_HANDLER, IPC_CONNECTOR>::getConnector_() const {
    return connector_;
}

template <class SERVICE_HANDLER, class IPC_CONNECTOR> void Connector<SERVICE_HANDLER, IPC_CONNECTOR>::setConnector_(IPC_CONNECTOR* p_connector_) {
    connector_ = p_connector_;
}

template <class SERVICE_HANDLER, class IPC_CONNECTOR> void Connector<SERVICE_HANDLER, IPC_CONNECTOR>::cleanUpRelations() {
    {
        itsServiceHandler.clear();
    }
}

template <class SERVICE_HANDLER, class IPC_CONNECTOR> Connector<SERVICE_HANDLER, IPC_CONNECTOR>::~Connector() {
    cleanUpRelations();
}

#endif
/*********************************************************************
	File Path	: DefaultComponent\CodeConfig\Connector.h
*********************************************************************/
